package org.hepeng.workx.spring.session.redis.serializer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import net.bytebuddy.dynamic.loading.ByteArrayClassLoader;
import org.joor.Reflect;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.util.HashMap;
import java.util.Map;

/**
 * @author he peng
 */
public class GenericJackson2SafetyClassBytesHandler extends AbstractSafetyRedisHttpSessionMessageReceiver {

    public GenericJackson2SafetyClassBytesHandler(RedisSerializer serializer) {
        super(serializer);
    }

    @Override
    protected void handleClassBytes(String className, byte[] classBytes) {
        GenericJackson2JsonRedisSerializer jackson2Serializer = (GenericJackson2JsonRedisSerializer) super.serializer;
        ObjectMapper mapper = Reflect.on(jackson2Serializer).get("mapper");
        TypeFactory typeFactory = mapper.getTypeFactory();
        Map<String, byte[]> oldTypeDefinitions = Reflect.on(typeFactory.getClassLoader()).get("typeDefinitions");
        Map<String, byte[]> typeDefinitions = new HashMap<>(oldTypeDefinitions);
        typeDefinitions.put(className , classBytes);
        ByteArrayClassLoader classLoader =
                new ByteArrayClassLoader(ClassLoader.getSystemClassLoader(), typeDefinitions);
        Reflect.on(typeFactory).set("_classLoader" , classLoader);
        mapper.setTypeFactory(typeFactory);
    }


}
